#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@File   : test01_storage_management.py
@Time : 2024/12/20 15:05
@Author: Wangwc
@Describe:  ……
"""
import time
import random
import allure
import pytest

from business.DiskApi import DiskApi
from commons.logger import log
from utils.login import Login

# TODO 当前模块的配置文件名称，配置在config目录下
config_name = 'cloud.ini'
login = Login(config_name=config_name)
# 默认使用管理员账号登录，如果想切换账号，也可以使用 login = Login(user='user2',config_name=config_name)

# 在脚本开头添加全局变量
global_token = None

@pytest.fixture(scope="function")
def init_api():
    global global_token
    login.http_request.update_base_url()
    if global_token is None:
        global_token = login.login()
    api = DiskApi(global_token, configname=config_name)
    api.http.update_base_url()
    return api


def handle_api_call(api_method, *args, attach_to_allure=True, format_result=None, **kwargs):
    if not callable(api_method):
        raise TypeError("api_method 参数必须是可调用对象（如函数或方法）")
    if attach_to_allure is not None and not isinstance(attach_to_allure, bool):
        raise TypeError("attach_to_allure 参数必须是布尔类型或者为 None")
    if format_result is not None and not callable(format_result):
        raise TypeError("format_result 参数必须是可调用对象（如函数）或者为 None")

    max_retries = 3
    for retry in range(max_retries):
        try:
            result = api_method(*args, **kwargs)
            if attach_to_allure:
                if format_result:
                    formatted_result = format_result(result)
                else:
                    formatted_result = str(result)
                allure.attach(formatted_result, f"{api_method.__name__} 调用结果", allure.attachment_type.TEXT)
            log.info(f"{api_method.__name__} 调用成功")
            return result
        except Exception as e:
            allure.attach(str(e), f"{api_method.__name__} 调用错误信息", allure.attachment_type.TEXT)
            log.error(f"{api_method.__name__} 调用出现错误: {e}", exc_info=True)
            # 假设根据错误信息判断 token 过期
            if "token 过期" in str(e) and retry < max_retries - 1:
                global global_token
                global_token = login.login()
                api_method.__self__.token = global_token
                continue
            elif isinstance(e, ConnectionError):
                log.error("连接错误，可能是网络问题，请检查网络连接。")
            elif isinstance(e, ValueError):
                log.error("值错误，可能是传入的参数有误，请检查参数。")
            raise


@allure.feature("存储管理")
class TestStorageManagement():
    @allure.title("创建存储池与存储空间")
    def test_creat_pool_and_volumes(self, init_api):
        log.info(f"开始执行用例：创建存储池与存储空间{'-' * 20}")
        with allure.step("获取未使用的硬盘名称列表"):
            log.info(f"开始获取未使用的硬盘列表")
            disk_info = handle_api_call(init_api.get_unused_disk_name)
            log.info(f"成功获取未使用的硬盘列表为: {disk_info}")

        with allure.step("创建raid1的存储池"):
            log.info(f"开始创建raid1的存储池")
            handle_api_call(init_api.creat_pool)
            log.info("确认存储池创建成功")
            if handle_api_call(init_api.check_pool_status,status=1):
                log.info("存储池创建成功,存储池在同步中……")

        with allure.step("在存储池上创建10G的存储空间1,文件系统btrfs"):
            pool_name = handle_api_call(init_api.get_pool_name_list)[0]
            log.info(f"获取存储池名称为：{pool_name}")
            log.info(f"在存储池上创建100G的存储空间")
            handle_api_call(init_api.create_volume_withpool,pool_name, "10GB", "btrfs")

        with allure.step("在存储池上创建20G的存储空间2,文件系统ext4"):
            pool_name = handle_api_call(init_api.get_pool_name_list)[0]
            log.info(f"获取存储池名称为：{pool_name}")
            log.info(f"在存储池上创建100G的存储空间")
            handle_api_call(init_api.create_volume_withpool,pool_name, "20GB", "ext4")

        with allure.step("确认存储池与存储空间创建完成"):
            log.info(f"确认存储池与存储空间创建完成")
            pool_info = handle_api_call(init_api.get_pool_list)
            log.info(f"获取存储池信息为：{pool_info}")
            volumes = pool_info[0].get("volumes")
            assert len(volumes) == 2, f"存储池{pool_name}上创建的存储空间数量为{len(volumes)}，预期为2"
            log.info(f"创建存储池与存储空间测试用例完成，测试通过！{'-' * 20}")

    @allure.title("总览-校验硬盘状态")
    def test_check_disks_status(self, init_api):
        with allure.step("获取未使用的硬盘名称列表"):
            try:
                unused_disk = handle_api_call(init_api.get_unused_disk_name)
                assert len(unused_disk) == 4, f"未使用的硬盘数量为{len(unused_disk)}，预期为4"
            except Exception as e:
                log.error(f"获取未使用的硬盘名称列表失败: {str(e)}")
                raise  # 重新抛出异常以确保测试失败

        with allure.step("获取未使用的硬盘状态"):
            try:
                disk1_status = handle_api_call(init_api.get_disk_status,unused_disk[0],"status")
                disk2_status = handle_api_call(init_api.get_disk_status,unused_disk[1],"status")
                assert disk1_status == 1, f"硬盘{unused_disk[0]}的状态为{disk1_status}，预期为1"
                assert disk2_status == 1, f"硬盘{unused_disk[1]}的状态为{disk2_status}，预期为1"
            except Exception as e:
                log.error(f"获取硬盘状态失败: {str(e)}")
                raise  # 重新抛出异常以确保测试失败

    @allure.title("总览-存储管理器组件管理")
    def test_storage_widget_management(self, init_api):
        with allure.step("确认组件信息已清空"):
            handle_api_call(init_api.delete_widgets)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert widget_info is None, f"实际组件数量为{len(widget_info)}，预期为0"

        with allure.step("添加硬盘状态信息组件"):
            type = 1
            flags = [1, 2]
            handle_api_call(init_api.add_widget,type, flags)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert len(widget_info) == 1, f"实际组件数量为{len(widget_info)}，预期为1"

        with allure.step("添加存储空间状态信息组件"):
            type = 2
            flags = [0]
            handle_api_call(init_api.add_widget,type, flags)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert len(widget_info) == 2, f"实际组件数量为{len(widget_info)}，预期为2"

        with allure.step("添加定时任务计划组件"):
            type = 3
            flags = [0, 1, 2]
            handle_api_call(init_api.add_widget,type, flags)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert len(widget_info) == 3, f"实际组件数量为{len(widget_info)}，预期为3"

        with allure.step("添加硬盘性能监测组件"):
            type = 4
            flags = [0]
            handle_api_call(init_api.add_widget,type, flags)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert len(widget_info) == 4, f"实际组件数量为{len(widget_info)}，预期为4"

        with allure.step("添加存储空间性能监测组件"):
            type = 5
            flags = [0]
            handle_api_call(init_api.add_widget,type, flags)
            widget_info = handle_api_call(init_api.get_widget_list)
            assert len(widget_info) == 5, f"实际组件数量为{len(widget_info)}，预期为5"

        with allure.step("移动第3个组件到第2个位置"):
            flags_mapping = {
                1: [1, 2],
                2: [0],
                3: [0, 1, 2],
                4: [0],
                5: [0]
            }
            try:
                widget_info = handle_api_call(init_api.get_widget_list)
                type = widget_info[2].get("type")
                flags = flags_mapping.get(type, [0])  # 如果类型不存在字典中，默认使用[0]
                handle_api_call(init_api.change_widget_position,type, 2, 1, flags)
                index = handle_api_call(init_api.get_widget_position,type)
                assert index == 1, f"移动后实际组件的索引为：{index}，预期为1"
            except Exception as e:
                log.error(f"移动组件操作时出现异常，异常信息：{e}")
                raise

        with allure.step("删除1个组件"):
            try:
                widget_info = handle_api_call(init_api.get_widget_list)
                if widget_info:
                    max_index = len(widget_info) - 1
                    index = random.randint(0, max_index)
                    handle_api_call(init_api.delete_widget,index)
                    widget_info = handle_api_call(init_api.get_widget_list)
                    assert len(widget_info) == max_index, f"实际组件数量为{len(widget_info)}，预期为{max_index}"
                else:
                    log.info("组件列表为空，无法执行删除组件操作")
            except Exception as e:
                log.error(f"删除组件操作时出现异常，异常信息：{e}")
                raise

    @allure.title("存储空间扩容")
    def test_volume_throw(self, init_api):
        log.info(f"开始执行用例：存储空间扩容{'-' * 20}")
        with allure.step("获取存储空间devices信息"):
            log.info(f"开始获取存储空间devices信息")
            result = handle_api_call(init_api.get_pool_list)
            volumes = result[0].get("volumes")
            device = volumes[0].get("device")
            volume_name = volumes[0].get("name")
            log.info(f"存储空间设置的device信息为: {device}")
            size = volumes[0].get("total")
            log.info(f"存储空间{volume_name}扩容前的size信息为: {size}")

        with allure.step("存储空间扩容"):
            log.info(f"开始给存储空间{volume_name}扩容")
            handle_api_call(init_api.volume_grow,device, "100GB")
            if handle_api_call(init_api.check_volume_status):
                log.info(f"存储空间{volume_name}扩容成功")

        with allure.step("确认存储空间扩容成功"):
            log.info(f"确认存储空间扩容成功")
            new_result = handle_api_call(init_api.get_pool_list)
            volumes = new_result[0].get("volumes")
            new_size = None
            for volume in volumes:
                if volume.get("name") == volume_name:
                    new_size = volume.get("total")
                    break
            assert new_size > size, f"存储空间{volume_name}扩容后的size信息为{new_size}，预期大于{size}"

    @allure.title("创建SSD缓存")
    def test_create_cache(self, init_api):
        log.info(f"开始执行用例：创建SSD缓存{'-' * 20}")
        with allure.step("获取可作为SSD缓存的硬盘信息"):
            pool_list = handle_api_call(init_api.get_pool_list)
            pool_name = pool_list[0].get("name")
            available_list = handle_api_call(init_api.get_cache_availableDisks,pool_name)
            if available_list:
                cache_disk1_name = available_list[0].get("dev_name")
                cache_disk2_name = available_list[1].get("dev_name")
                disks = [cache_disk1_name, cache_disk2_name]
            else:
                disks = None

        with allure.step("给存储空间1创建SSD缓存"):
            volumes = pool_list[0].get("volumes")
            volume1_name = volumes[0].get("label")
            volume1_device = volumes[0].get("device")
            volume1_mntpath = volumes[0].get("mntpath")
            volume1_filesystem = volumes[0].get("filesystem")
            volume1 = {"device": volume1_device, "mount_point": volume1_mntpath, "filesystem": volume1_filesystem}
            handle_api_call(init_api.create_cache,volume1, disks)

        with allure.step("确认存储空间1成功创建SSD缓存"):
            cache = handle_api_call(init_api.get_cache_list,pool_name)
            cache_vols = cache.get("cache_vols")
            cache_volume1_name = cache_vols[0].get('for_vol').get('label')
            assert len(cache_vols) == 1, f"预期创建1个SSD缓存，实际创建{len(cache_vols)}个"
            assert cache_volume1_name == volume1_name, f"预期创建的SSD缓存存储空间为{volume1_name}，实际创建的为{cache_volume1_name}"

        with allure.step("给存储空间2创建SSD缓存"):
            cache_pool = cache.get("device")
            volume2_name = volumes[1].get("label")
            volume2_device = volumes[1].get("device")
            volume2_mntpath = volumes[1].get("mntpath")
            volume2_filesystem = volumes[1].get("filesystem")
            volume2 = {"device": volume2_device, "mount_point": volume2_mntpath, "filesystem": volume2_filesystem}
            handle_api_call(init_api.create_cache_withpool,volume2, cache_pool)

        with allure.step("确认存储空间2成功创建SSD缓存"):
            cache = handle_api_call(init_api.get_cache_list,pool_name)
            cache_vols = cache.get("cache_vols")
            cache_volume2_name = cache_vols[1].get('for_vol').get('label')
            assert len(cache_vols) == 2, f"预期创建1个SSD缓存，实际创建{len(cache_vols)}个"
            assert cache_volume2_name == volume2_name, f"预期创建的SSD缓存存储空间为{volume2_name}，实际创建的为{cache_volume2_name}"

    @allure.title("删除SSD缓存")
    def test_delete_cache(self, init_api):
        log.info(f"开始执行用例：删除SSD缓存{'-' * 20}")
        with allure.step("获取初始的SSD缓存信息"):
            pool_list = handle_api_call(init_api.get_pool_list)
            pool_name = pool_list[0].get("name")
            cache = handle_api_call(init_api.get_cache_list,pool_name)
            cache_vols = cache.get("cache_vols")
            cache_number = len(cache_vols)

        with allure.step("删除第1个存储空间的SSD缓存"):
            cache_pool = cache.get("device")
            cache1_name = cache_vols[0].get("name")
            handle_api_call(init_api.delete_cache_operation,cache_pool, cache_name=cache1_name)

        with allure.step("确认第1个存储空间的SSD缓存成功删除"):
            time.sleep(5)
            cache = handle_api_call(init_api.get_cache_list,pool_name)
            cache_vols = cache.get("cache_vols")
            cache_number1 = len(cache_vols)
            assert cache_number1 == cache_number - 1, f"预期删除1个SSD缓存，实际删除{cache_number1 - cache_number}个"

        with allure.step("删除整个SSD缓存"):
            handle_api_call(init_api.delete_cache_operation,cache_pool)

        with allure.step("确认所有SSD缓存都被删除"):
            time.sleep(5)
            cache = handle_api_call(init_api.get_cache_list,pool_name)
            cache_vols = cache.get("cache_vols")
            assert cache_vols is None, "预期删除所有SSD缓存，实际未删除"

    @allure.title("存储空间设置")
    def test_volume_setting(self, init_api):
        log.info(f"开始执行用例：存储空间设置{'-' * 20}")
        with allure.step("获取存储空间devices信息"):
            log.info(f"开始获取存储空间devices信息")
            pool_info = handle_api_call(init_api.get_pool_name_list)
            log.info(f"获取存储池信息为：{pool_info}")
            pool_name = pool_info[0]
            devices = handle_api_call(init_api.get_volume_devices,pool_name)
            if devices:
                log.info(f"成功获取存储空间devices信息为: {devices}")
                device = devices[0]
                log.info(f"存储空间设置的device信息为: {device}")
            else:
                log.warning(f"未获取到存储空间devices信息")
                return False

        with allure.step("获取存储空间设置信息"):
            log.info(f"开始获取存储空间设置信息")
            result = handle_api_call(init_api.get_volume_setting,device)
            log.info(f"获取存储空间设置返回的信息为:{result}")
            percent = result.get('percent')
            log.info(f"成功获取存储空间初始设置信息为: {percent}")

        with allure.step("更改存储空间设置信息"):
            log.info(f"开始更改存储空间设置信息")
            set_percent = 15
            handle_api_call(init_api.set_volume_setting,device, set_percent)
            log.info(f"成功更改存储空间设置信息为: {set_percent}%")

        with allure.step("确认成功更改存储空间设置"):
            log.info(f"再次获取存储空间设置信息")
            result = handle_api_call(init_api.get_volume_setting,device)
            log.info(f"获取存储空间设置返回的信息为:{result}")
            new_percent = result.get("percent")
            log.info(f"更改后的存储空间初始设置信息为: {new_percent}")
            assert new_percent == set_percent, f"更改后的存储空间设置信息为{new_percent}，预期为{set_percent}"

    @allure.title("性能修复设置")
    def test_volume_performance(self, init_api):
        log.info(f"开始执行用例：性能修复设置{'-' * 20}")
        with allure.step("获取存储空间性能修复设置信息"):
            log.info(f"开始获取存储空间性能修复设置信息")
            result = handle_api_call(init_api.get_pool_setting)
            mode = result.get('raid_speed_limit').get("mode")
            log.info(f"获取存储空间性能修复设置返回的信息为:{mode}")

        with allure.step("开始修改存储空间性能修复设置信息"):
            log.info(f"开始修改存储空间性能修复设置信息")
            set_mode = 1 if mode == 0 else 0
            result = handle_api_call(init_api.set_pool_setting,mode=set_mode)
            log.info(f"修改后存储空间性能设置的信息为:{result}")

        with allure.step("校验存储空间性能信息有成功修改"):
            log.info(f"校验存储空间性能信息有成功修改")
            result = handle_api_call(init_api.get_pool_setting)
            new_mode = result.get('raid_speed_limit').get("mode")
            assert new_mode == set_mode, f"修改后的存储空间性能设置信息为{new_mode}，预期为{set_mode}"

    @allure.title("快速修复设置")
    def test_quick_fix(self, init_api):
        log.info(f"开始执行用例：快速修复设置{'-' * 20}")
        with allure.step("获取存储空间快速修复设置信息"):
            log.info(f"开始获取存储空间快速修复设置信息")
            result = handle_api_call(init_api.get_pool_setting)
            bitmap = result.get('bitmap').get("enable")
            log.info(f"获取获取存储空间快速修复设置信息为:{bitmap}")

        with allure.step("开始修改存储空间快速修复设置信息"):
            log.info(f"开始修改存储空间快速修复设置信息")
            set_bitmap = 1 if bitmap == 0 else 0
            result = handle_api_call(init_api.set_pool_setting,bitmap=set_bitmap)
            log.info(f"修改后存储空间快速修复设置为:{result}")

        with allure.step("校验存储空间快速修复设置有成功修改"):
            log.info(f"校验存储空间快速修复设置有成功修改")
            result = handle_api_call(init_api.get_pool_setting)
            new_bitmap = result.get('bitmap').get("enable")
            assert new_bitmap == set_bitmap, f"修改后的存储空间快速修复设置为{new_bitmap}，预期为{set_bitmap}"

    @allure.title("获取存储空间使用情况")
    def test_get_volume_usage(self, init_api):
        log.info(f"开始执行用例：获取存储空间使用情况{'-' * 20}")
        with allure.step("获取存储池名称"):
            log.info(f"开始获取存储池名称")
            pool_info = handle_api_call(init_api.get_pool_name_list)
            pool_name = pool_info[0]
            log.info(f"获取存储池名称为：{pool_name}")

        with allure.step("获取存储空间名称"):
            log.info(f"开始获取存储空间名称")
            pool_list = handle_api_call(init_api.get_pool_list)
            volumes = pool_list[0].get("volumes")
            volum_name = volumes[0].get("name")
            log.info(f"获取存储空间名称为：{volum_name}")

        with allure.step("获取存储空间使用情况"):
            log.info(f"获取存储空间使用情况")
            result = handle_api_call(init_api.get_volume_spaceUsage,pool_name, volum_name)
            assert result.get("available") is not None, f"获取存储空间使用情况失败，返回结果为：{result}"

    @allure.title("删除存储池与存储空间")
    def test_delete_pool_and_volumes(self, init_api):
        log.info(f"开始执行用例：删除存储池与存储空间{'-' * 20}")
        with allure.step("获取存储池与存储空间信息"):
            log.info(f"开始获取存储池与存储空间信息")
            pool_info = handle_api_call(init_api.get_pool_name_list)
            log.info(f"获取存储池信息为：{pool_info}")
            pool_name = pool_info[0]
            volume_info = handle_api_call(init_api.get_volume_devices,pool_name)
            log.info(f"获取存储空间信息为：{volume_info}")

        with allure.step("删除存储空间"):
            log.info(f"开始删除存储空间")
            if volume_info:
                log.info("有未删除的存储空间，开始删除存储空间")
                handle_api_call(init_api.delete_volume,volume_info[0])
            else:
                log.info("没有存储空间需要删除")

        with allure.step("确认有成功删除存储空间"):
            time.sleep(25)
            log.info(f"确认有成功删除存储空间")
            volume_info2 = handle_api_call(init_api.get_volume_devices,pool_name)
            assert len(volume_info2) == len(
                volume_info) - 1, f"删除存储空间失败，删除前有{len(volume_info)}个存储空间，删除后还有{len(volume_info2)}个存储空间"

        with allure.step("删除存储池"):
            log.info(f"开始删除存储池")
            if pool_info:
                log.info("有未删除的存储池，开始删除存储池")
                handle_api_call(init_api.delete_pool_info)
            else:
                log.info("没有存储池需要删除")

        with allure.step("确认有成功删除存储池"):
            time.sleep(10)
            log.info(f"确认有成功删除存储池")
            pool_info2 = handle_api_call(init_api.get_pool_name_list)
            assert len(pool_info2) == len(pool_info) - 1, f"删除存储池失败，删除前有{len(pool_info)}个存储池，删除后还有{len(pool_info2)}个存储池"

    @allure.title("存储池管理-修复存储池")
    def test_fix_pool(self, init_api):
        log.info("开始执行修复存储池测试用例")
        with allure.step("使用shell脚本创建小容量的raid1"):
            try:
                pool_list = handle_api_call(init_api.create_raid1,size=10)
                pool_name = pool_list[0].get("name")
                log.info(f"获取到的初始存储池信息为: {pool_name}")
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise
        with allure.step("停用一块硬盘"):
            try:
                disk_name1 = handle_api_call(init_api.get_used_disk_name)[0]
                log.info(f"待停用的硬盘信息为：{disk_name1}")
                handle_api_call(init_api.stop_use_disk,disk_name1)
            except Exception as e:
                log.error(f"删除存储池时出现异常，异常信息: {e}")
                raise
        with allure.step("确认硬盘停用成功"):
            try:
                time.sleep(3)
                disk_usage = handle_api_call(init_api.get_disk_status,disk_name1,'usage')
                assert disk_usage == 6, f"硬盘停用失败，当前硬盘状态为：{disk_usage}"
            except Exception as e:
                log.error(f"获取硬盘状态时出现异常，异常信息: {e}")
                raise
        with allure.step("修复存储池"):
            try:
                disk_name2 = handle_api_call(init_api.get_unused_disk_name)[0]
                log.info(f"修复存储池使用的硬盘信息为：{disk_name2}")
                pool_name = handle_api_call(init_api.get_pool_name_list)[0]
                log.info(f"待修复的存储池信息为：{pool_name}")
                handle_api_call(init_api.fix_pool,disk_name2, pool_name)
            except Exception as e:
                log.error(f"获取存储池信息时出现异常，异常信息: {e}")
                raise

        with allure.step("确认存储池修复完成"):
            try:
                handle_api_call(init_api.check_pool_status)
                time.sleep(5)
                log.info("存储池成功修复完成")
            except Exception as e:
                log.error(f"获取存储池信息时出现异常，异常信息: {e}")
                raise

        with allure.step("确认存储池修复后硬盘信息有变更"):
            disk_list = handle_api_call(init_api.get_used_disk_name)
            assert disk_name1 not in disk_list, f"修复存储池后硬盘信息未变更，请重新修复存储池"
            log.info("修复存储池后硬盘信息有变更")

        with allure.step("将停用的硬盘重新启用"):
            try:
                time.sleep(1)
                handle_api_call(init_api.start_use_disk,disk_name1)
                handle_api_call(init_api.check_pool_status)
                time.sleep(5)
            except Exception as e:
                log.error(f"删除存储池时出现异常，异常信息: {e}")
                raise

        with allure.step("确认硬盘启用成功"):
            try:
                time.sleep(3)
                disk_usage = handle_api_call(init_api.get_disk_status,disk_name1,'usage')
                assert disk_usage == 0, f"硬盘停用失败，当前硬盘状态为：{disk_usage}"
            except Exception as e:
                log.error(f"获取硬盘状态时出现异常，异常信息: {e}")
                raise

    @allure.title("添加热备盘")
    def test_add_spare(self, init_api):
        log.info("开始执行添加热备盘测试用例")
        with allure.step("获取存储池信息"):
            try:
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                raid_name = pool_list[0].get("pvs")
                log.info(f"获取到的初始raid信息为: {raid_name}")
                spare = pool_list[0].get("spare")
                log.info(f"获取到的初始热备盘信息为: {spare}")
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

        with allure.step("获取添加热备盘前的硬盘信息"):
            try:
                unused_disks = handle_api_call(init_api.get_unused_disk_name)
                log.info(f"获取到的替换前的已使用的硬盘信息为: {unused_disks}")
                disk_name = unused_disks[0]
                log.info(f"获取到的未使用的硬盘信息为: {disk_name}")
            except Exception as e:
                log.error(f"创建存储池时出现异常，异常信息: {e}")
                raise

        with allure.step("添加热备盘"):
            try:
                handle_api_call(init_api.check_pool_status)
                time.sleep(5)
                handle_api_call(init_api.creat_spare,raid_name, disk_name)
                log.info("已发送替换硬盘请求，等待替换完成")
            except Exception as e:
                log.error(f"替换硬盘时出现异常，异常信息: {e}")
                raise

        with allure.step("确认成功添加热备盘"):
            try:
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                spare = pool_list[0].get("spare")
                log.info(f"获取到的初始热备盘信息为: {spare}")
                assert spare[0].get("dev_name") == disk_name, "添加热备盘失败"
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

        with allure.step("取消热备盘"):
            try:
                handle_api_call(init_api.stop_use_disk,disk_name)
                time.sleep(1)
                handle_api_call(init_api.start_use_disk,disk_name)
                handle_api_call(init_api.check_pool_status)
                time.sleep(5)
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

    @allure.title("更换存储池RAID类型")
    def test_up_raid(self, init_api):
        log.info("开始执行更换存储池RAID类型测试用例")
        with allure.step("获取存储池信息"):
            try:
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                pool_name = pool_list[0].get("name")
                log.info(f"获取到的存储池名称为为: {pool_name}")
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

        with allure.step("获取未使用的硬盘信息"):
            try:
                unused_disks = handle_api_call(init_api.get_unused_disk_name)
                log.info(f"获取到的替换前的已使用的硬盘信息为: {unused_disks}")
                disk_name = unused_disks[0]
                log.info(f"获取到的未使用的硬盘信息为: {disk_name}")
            except Exception as e:
                log.error(f"创建存储池时出现异常，异常信息: {e}")
                raise

        with allure.step("升级RAID类型"):
            try:
                handle_api_call(init_api.up_raid,pool_name, disk_name)
                log.info("已发送替换硬盘请求，等待替换完成")
            except Exception as e:
                log.error(f"替换硬盘时出现异常，异常信息: {e}")
                raise

        with allure.step("确认成功升级raid类型"):
            try:
                if handle_api_call(init_api.check_pool_status):
                    time.sleep(5)
                    log.info(f"raid升级已经完成，开始校验raid类型")
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                raid_type = pool_list[0].get("level")
                assert raid_type == "raid5", "更换存储池RAID类型失败"
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

    @allure.title("存储池数据整理")
    def test_pool_scrub(self, init_api):
        log.info("开始执行存储池数据整理测试用例")
        with allure.step("获取存储池信息，确认状态"):
            try:
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                pool_name = pool_list[0].get("name")
                pool_level = pool_list[0].get("label")
                pool_status = pool_list[0].get("status")
                log.info(f"获取到的存储池信息为，存储池名称: {pool_name}、存储池等级：{pool_level}、存储池状态：{pool_status}")
            except Exception as e:
                log.error(f"获取存储池信息时出现异常，异常信息: {e}")
                raise

        with allure.step("开始存储池数据整理"):
            try:
                handle_api_call(init_api.pool_scrub,pool_name)
            except Exception as e:
                log.error(f"存储池数据整理时出现异常，异常信息: {e}")
                raise

        with allure.step("确认有进行存储池数据整理"):
            try:
                time.sleep(3)
                pool_list = handle_api_call(init_api.get_pool_list)
                pool_status = pool_list[0].get("status")
                assert pool_status == 5, f"存储池数据整理失败，实际状态为：{pool_status}"

            except Exception as e:
                log.error(f"确认有进行存储池数据整理时出现异常，异常信息: {e}")
                raise

        with allure.step("停止存储池数据整理"):
            try:
                handle_api_call(init_api.stop_pool_scrub,pool_name)
            except Exception as e:
                log.error(f"停止存储池数据整理时出现异常，异常信息: {e}")
                raise

        with allure.step("确认有成功停止存储池数据整理"):
            try:
                time.sleep(3)
                pool_list = handle_api_call(init_api.get_pool_list)
                pool_status = pool_list[0].get("status")
                assert pool_status == 0, f"停止存储池数据整理失败，实际状态为：{pool_status}"
            except Exception as e:
                log.error(f"确认有进行存储池数据整理时出现异常，异常信息: {e}")
                raise

    @allure.title("存储池扩容")
    def test_ext_pool(self, init_api):
        log.info("开始执行使用硬盘-添加到存储池测试用例")
        with allure.step("获取存储池信息"):
            try:
                pool_list = handle_api_call(init_api.get_pool_list)
                log.info(f"获取到的初始存储池信息为: {pool_list}")
                pool_name = pool_list[0].get("name")
                old_size = pool_list[0].get('total')
                log.info(f"获取到的存储池名称为: {pool_name}")
            except Exception as e:
                log.error(f"获取存储池数量时出现异常，异常信息: {e}")
                raise

        with allure.step("获取未使用的硬盘信息"):
            try:
                unused_disks = handle_api_call(init_api.get_unused_disk_name)
                log.info(f"获取到的未使用的硬盘信息为: {unused_disks}")
                disk_name = unused_disks[0]
                log.info(f"获取到的未使用的硬盘信息为: {disk_name}")
            except Exception as e:
                log.error(f"创建存储池时出现异常，异常信息: {e}")
                raise

        with allure.step("存储池扩容"):
            try:
                handle_api_call(init_api.check_pool_status)
                time.sleep(15)
                handle_api_call(init_api.extend_pool,pool_name, disk_name)
                log.info("已发送存储池扩容请求，等待存储池扩容完成")
            except Exception as e:
                log.error(f"存储池扩容时出现异常，异常信息: {e}")
                raise

        with allure.step("确认存储池扩容成功"):
            try:
                handle_api_call(init_api.check_pool_status)
                time.sleep(3)
                pool_list = handle_api_call(init_api.get_pool_list)
                new_size = pool_list[0].get('total')
                assert new_size > old_size, f"存储池扩容失败，实际存储池大小为：{new_size}，原存储池大小为：{old_size}"
            except Exception as e:
                log.error(f"存储池扩容时出现异常，异常信息: {e}")
                raise

        with allure.step("删除存储池"):
            log.info("开始删除存储池，清理测试环境")
            try:
                handle_api_call(init_api.delete_pool_info)
            except Exception as e:
                log.error(f"删除存储池时出现异常，异常信息: {e}")
                raise
